package edu.shiep.sunyu;

import java.io.IOException;
import java.text.ParseException;
import java.util.Date;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCursor;

import edu.shiep.sunyu.model.Booking;
import edu.shiep.sunyu.model.Bus;
import edu.shiep.sunyu.model.DBClient;
import edu.shiep.sunyu.model.DBConstants;
import edu.shiep.sunyu.model.Database;
import edu.shiep.sunyu.model.Table;
import edu.shiep.sunyu.model.User;

public class BookingBusServlet extends HttpServlet  {

	private static final long serialVersionUID = 8436779686026448171L;
	
	private DBClient _client = null;
	
	public void init(ServletConfig config) throws ServletException {
	   super.init(config);
	   
	   _client = new DBClient();
	   if (!_client.connect()) {
		   System.out.println("Can't connect to database!!!");
	   }
	}
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) 
			throws ServletException, IOException {
		// reading the user input
		String bus_id = request.getParameter("bus_id");
		String bus_date_year = request.getParameter("bus_date_year");
		String bus_date_month = request.getParameter("bus_date_month");
		String bus_date_day = request.getParameter("bus_date_day");
		String bus_time = request.getParameter("bus_time");
		String bus_date = bus_date_year + "-" + bus_date_month + "-" + bus_date_day;
		
		// here should check session id, if there is no session id, we should redirect to login page
		HttpSession session = request.getSession(false);
		if (session == null) {
			request.setAttribute("msg",	"Please log into the booking system, and try again.");
			
			RequestDispatcher view = request.getRequestDispatcher("BookingLogin.jsp");
			view.forward(request, response);
			
			return;
		}
		
		String user_id = (String)session.getAttribute("user");
		boolean is_guest = (Boolean)session.getAttribute("is_guest");
		
		Database db = _client.getDB(DBConstants.Const_Database_Name);
		
		Table table = db.getTable(DBConstants.Const_Table_Booking_Name);
		
		if (!is_guest) {
			// Check if this user has booked before
			BasicDBObject query = new BasicDBObject();
			query.put(Booking.Field_Bus_Id, bus_id);
			query.put(Booking.Field_User_Id, user_id);
			query.put(Booking.Field_Date, bus_date);
			query.put(Booking.Field_Time, bus_time);
			
			DBCursor cursor = table.query(query);
	        if (cursor.count() != 0) {
	        	// forward to error page
				request.setAttribute("msg",	"You have booked this schedule, please try another one.");
				
				RequestDispatcher view = request.getRequestDispatcher("BookingSelectBus.jsp");
				view.forward(request, response);
	        	return;
	        }
		}
		
		BasicDBObject booking_query = new BasicDBObject();
		booking_query.put(Booking.Field_Bus_Id, bus_id);
		DBCursor bus_cursor = table.query(booking_query);
        int current_booking_count = bus_cursor.count();
        
		table = db.getTable(DBConstants.Const_Table_Bus_Name);
		BasicDBObject bus_query = new BasicDBObject();
		bus_query.put(Bus.Field_Id, bus_id);
		bus_cursor = table.query(bus_query);
		
		if (bus_cursor.hasNext()) { 
        	BasicDBObject busDoc = (BasicDBObject)bus_cursor.next();
        	Bus bus = new Bus();
        	bus.deserialize(busDoc);
        	
        	int ahead_of_min = bus.getAhead();
        	
        	Date date = null;
        	long span = 0;
        	try {
				date = Utility.buildBusTimeFromDatabase(bus_date, bus_time);
				span = Utility.getSpanFromNow(date) / 60;
			} catch (ParseException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        	
        	if (date == null) {
        		request.setAttribute("msg",	"A failure happened in the system, please try again.");
			
        		RequestDispatcher view = request.getRequestDispatcher("BookingSelectBus.jsp");
        		view.forward(request, response);
        		return;
        	}
        	
        	if (span < 0) {
        		request.setAttribute("msg",	"The time is less than current time, please try again.");
    			
        		RequestDispatcher view = request.getRequestDispatcher("BookingSelectBus.jsp");
        		view.forward(request, response);
        		return;
        	}
        	
        	if (bus.getSeat() - current_booking_count <= bus.getReserve()) {
        		// Check if the user is teacher, book it anyway.
        		table = db.getTable(DBConstants.Const_Admin_User_Name);
        		BasicDBObject user_query = new BasicDBObject();
        		user_query.put(User.Field_Id, user_id);
        		DBCursor user_cursor = table.query(bus_query);
        		if (user_cursor.hasNext()) { 
                	BasicDBObject userDoc = (BasicDBObject)user_cursor.next();
                	User user = new User();
                	user.deserialize(userDoc);
                	
                	if (!user.equals("teacher") && span >= ahead_of_min) {
        	        	// forward to error page
        				request.setAttribute("msg",	"This bus is full, please try another one.");
        				
        				RequestDispatcher view = request.getRequestDispatcher("BookingSelectBus.jsp");
        				view.forward(request, response);
        	        	return;
                	}
        		}
        	}
        }

		table = db.getTable(DBConstants.Const_Table_Booking_Name);
		BasicDBObject document = new BasicDBObject();
		document.put(Booking.Field_Bus_Id, bus_id);
		document.put(Booking.Field_User_Id, user_id);
		document.put(Booking.Field_Date, bus_date);
		document.put(Booking.Field_Time, bus_time);
		
		table.insert(document);

    	// forward to error page
		request.setAttribute("msg",	"You have booked the bus successfully. You could book another one.");
		
		RequestDispatcher view = request.getRequestDispatcher("BookingSelectBus.jsp");
		view.forward(request, response);
	}
	
}
